<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>7.着色器实现像素动画-小试牛刀（粒子爆炸效果）</title>
    <style>
        canvas{
            border:1px solid #aaa;
            margin: 0 auto;
            display: block;
        }
    </style>
</head>
<body>
    <canvas width="554" height="554"></canvas>
    <script src="/common/lib/gl-renderer.js"></script>

    <script type="module">
        import { loadImage, toPolar, fromPolar } from "/common/lib/utils.js";
        import {Animator} from '/common/lib/animator.js';

        /**
         * gl-renderer五步法
         * 1.创建renderer对象
         * 2.创建并启用webgl程序
         * 3.设置uniform变量
         * 4.将定点数据送入缓冲区
         * 5.渲染
         * 
         */
        // 1.
        (async function(){
            let canvas = document.querySelector("canvas");
            const renderer = new GlRenderer(canvas);

            // 2.
            const vertex = `
                attribute vec2 a_vertexPosition;
                attribute vec2 uv;
                varying vec2 vUv;

                void main(){
                    gl_PointSize = 1.0;
                    vUv = uv;
                    gl_Position = vec4(a_vertexPosition, 1.0, 1.0);
                }
            `
            // 
            const fragment = `
                #ifdef GL_ES
                precision highp float;
                #endif

                uniform sampler2D tMap;
                uniform float uTime;
                varying vec2 vUv;

                float random (vec2 st) {
                    return fract(sin(dot(st.xy,
                                        vec2(12.9898,78.233)))*
                        43758.5453123);
                }
                // 二维噪声，对st与方形区域的四个顶点插值
                float noise(vec2 st) {
                    vec2 i = floor(st);
                    vec2 f = fract(st);
                    vec2 u = f * f * (3.0 - 2.0 * f);
                    // st与方形区域的四个顶点做插值计算
                    return mix( mix( random( i + vec2(0.0,0.0) ), random( i + vec2(1.0,0.0) ), u.x),
                                mix( random( i + vec2(0.0,1.0) ), random( i + vec2(1.0,1.0) ), u.x), u.y);
                }
                float easing(float p){
                    return clamp(p * (2.0 - p), 0.0, 1.0);
                }

                void main() {
                    vec2 st = (vUv - 0.5) * vec2(2.0, 4.0) + 0.5;
                    vec2 uv = vUv + 1.0 - 2.0 * random(floor(st));
                    st = mix(vec2(0.0), vec2(1.0), st);
                    vec4 color = texture2D(tMap, mix(st, uv, easing(uTime)) );
                    gl_FragColor = color;
                }
            `

            const program = renderer.compileSync(fragment, vertex);
            renderer.useProgram(program);
    
            const texture = await renderer.loadTexture("https://p1.ssl.qhimg.com/t01cca5849c98837396.jpg");
    
            renderer.uniforms.tMap = texture;
            renderer.uniforms.uTime = 0.0
            
            renderer.setMeshData([{
                positions: [
                    [-1, -1],
                    [-1, 1],
                    [1, 1],
                    [1, -1],
                ],
                attributes: {
                    uv: [
                        [0, 0],
                        [0, 1],
                        [1, 1],
                        [1, 0],
                    ],
                },
                cells: [[0, 1, 2], [2, 0, 3]],
            }]);
            renderer.render();
    
            function update(uTime){
                renderer.uniforms.uTime = uTime/2000
                requestAnimationFrame(update)
            }
    
            update(0.0)
        })()

    </script>
</body>
</html>